/*******************************************************************************
 * Copyright (c) 2004 Ultimania Organization. All rights reserved. This program
 * and the accompanying materials are made available under the terms of the
 * Eclipse Public License v1.0 which accompanies this distribution, and is
 * available at http://www.eclipse.org/org/documents/epl-v10.html
 * 
 * Contributors: tidus - initial implementation.
 ******************************************************************************/

package org.ultimania.middlegenide.core;

import java.io.File;
import java.util.ArrayList;
import java.util.MissingResourceException;
import java.util.Properties;
import java.util.ResourceBundle;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.jface.dialogs.Dialog;

public class HibernateSubPlugin extends SubPlugin {
	private HibernateDialog dialog = null;

	private Combo cascade = null;
	private Combo version = null;

	private static final String HIBERNATE_CASCADE = "hibernate_cascade";

	private static final String BUILD_TEMPLATE = "build-hibernate.xml.vm";

	private static final String CFG_TEMPLATE = "hibernate.cfg.xml.vm";

	private static final String RESOURCE = "resource/hibernate-jars";

	private static final String[] VERSION_LIST = new String[] { "2.1",
		"3.0" };
	
	private static final String VERSION="version";

	private static final String[] CASCADE_LIST = new String[] { "all",
		"save-update", "delete", "all-delete-orphan", "none" };

	private static ResourceBundle rb = ResourceBundle
			.getBundle("org.ultimania.middlegenide.core.hibernate-dialect");

	ArrayList hbmFiles = new ArrayList();

	public HibernateSubPlugin(Properties property) {
		// set jar repositry.
		jarDir = RESOURCE;
		this.property = property;
		String c = property.getProperty(HIBERNATE_CASCADE);
		if (c == null)
			property.setProperty(HIBERNATE_CASCADE, "all");
		String v = property.getProperty(VERSION);
		if (c == null)
			property.setProperty(VERSION, "3.0");
	}

	public void generate() throws GeneratorException {
		try {
			// generate build file.
			mergeTemplate(BUILD_TEMPLATE, buildFile);

			// run ant. Then mapping files and JavaBeans are generated.
			runAnt();

			// generate hibernate configuration file.
			setProperty("mapping", findHbmFiles());
			String driver = (String) getProperty("database_driver");
			String dialect = null;
			try {
				dialect = rb.getString(driver);
				String v = property.getProperty(VERSION);
				if(!v.equals("3.0")){
					dialect = dialect.replaceFirst("org","net.sf");
				}
				
				
			} catch (MissingResourceException ex) {
				dialect = "net.sf.hibernate.dialect.GenericDialect";
			}

			setProperty("dialect", dialect);

			mergeTemplate(CFG_TEMPLATE, new File(destDir.getAbsolutePath()
					+ "/" + "hibernate.cfg.xml"));
		} catch (Exception e) {
			throw new GeneratorException(e);
		}
	}

	public void configure(Properties p) {
		dialog = new HibernateDialog(Display.getCurrent().getActiveShell());
		dialog.setProperties(p);
		dialog.create();
		dialog.open();
		dialog.close();
	}

	ArrayList findHbmFiles() {
		return findHbmFiles(destDir);
	}

	ArrayList findHbmFiles(File dir) {
		File[] files = dir.listFiles();
		for (int i = 0; i < files.length; i++) {
			if (files[i].isDirectory()) {
				findHbmFiles(files[i]);
			} else if (files[i].isFile()) {
				String name = files[i].getName();
				if (name.indexOf(".hbm.xml", name.length()
						- ".hbm.xml".length()) != -1) {
					String path = files[i].getAbsolutePath();
					path = path.substring(
							destDir.getAbsolutePath().length() + 1,
							path.length()).replace('\\', '/');
					hbmFiles.add(path);
				}
			}
		}
		return hbmFiles;
	}

	public static void main(String args[]) {
		HibernateSubPlugin p = new HibernateSubPlugin(new Properties());
		p.configure();
	}

	class HibernateDialog extends Dialog {
		Properties p;

		void setProperties(Properties p) {
			this.p = p;
		}

		protected Control createDialogArea(Composite container) {
			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
			GridLayout layout = new GridLayout();
			layout.numColumns = 2;
			layout.verticalSpacing = 9;

			container.setLayout(layout);
			Label l = new Label(container, SWT.NULL);
			l.setText("Cascade:");

			cascade = new Combo(container, SWT.BORDER|SWT.SINGLE);
			cascade.setItems(CASCADE_LIST);
			String c = p.getProperty(HIBERNATE_CASCADE);

			for (int j = 0; j < CASCADE_LIST.length; j++) {
				if (c.equals(CASCADE_LIST[j])) {
					cascade.select(j);
				}
			}
			cascade.setLayoutData(gd);
			
			l = new Label(container, SWT.NULL);
			l.setText("Version:");
			version = new Combo(container, SWT.BORDER|SWT.SINGLE);
			version.setItems(VERSION_LIST);
			version.select(1);
			version.setLayoutData(gd);

			return super.createDialogArea(container);
		}

		public HibernateDialog(Shell parent) {
			super(parent);
		}

		protected void configureShell(Shell newShell) {
			newShell.setText("Hibernate Configuration");
			super.configureShell(newShell);
		}
		
		protected void buttonPressed(int buttonId) {
			if(buttonId==Dialog.OK){
				p.setProperty(HIBERNATE_CASCADE, (String) cascade.getItem(cascade
						.getSelectionIndex()));
				p.setProperty(VERSION, (String) version.getItem(version
						.getSelectionIndex()));
			}
			super.buttonPressed(buttonId);
		}
		
		protected void constrainShellSize() {
 			Shell shell = getShell();
 			shell.pack();
		}
		
	}
}